package model;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

import org.apache.log4j.Logger;

public class User implements Serializable, HttpSessionBindingListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 5819839094412663867L;
	
	private static Logger logger = Logger.getLogger(User.class);
	
	/**
	 * This map stores all the logged users. It serves to login with the same user twice or more times. 
	 */
	private static Map<User,HttpSession> loggedUsers = new HashMap<User,HttpSession>();
	
	private String email;
	private String password;
	private int id;
	private int tipoUsuario;
	private int age;
	private Date signUpDate;

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setId(int id) {
		this.id = id;
	}

	public int getId() {
		return id;
	}

	public int getTipoUsuario() {
		return tipoUsuario;
	}

	public void setTipoUsuario(int tipoUsuario) {
		this.tipoUsuario = tipoUsuario;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Date getSignUpDate() {
		return signUpDate;
	}

	public void setSignUpDate(Date signUpDate) {
		this.signUpDate = signUpDate;
	}

	public boolean equals(Object o) {
		if (o == null) {
			return false;
		} else if (getEmail() != null && getPassword() != null
				&& o instanceof User) {
			User anUser = (User) o;

			return getEmail().equalsIgnoreCase(anUser.getEmail())
					&& getPassword().equals(anUser.getPassword());

		} else {
			return false;
		}
	}

	public int hashCode() {
		int result = 17;
		result = 31 * result + (getEmail() != null ? getEmail().hashCode() : 0);
		result = 31 * result
				+ (getPassword() != null ? getPassword().hashCode() : 0);
		return result;
	}

	@Override
	public void valueBound(HttpSessionBindingEvent event) {
		
		logger.info(String.format("Bounding (user,email, session)=(%d,%s,%s)", this.getId(), this.getEmail(), event.getSession()));
		
		// Firstly, we assume that the user has been already logged in.
		HttpSession session = loggedUsers.remove(this);
		
		if (session != null ) {
			// Yes, that's right, the user was already logged in => let's invalidate his/her previous session.
			logger.info(String.format("The user WAS already logged in. Invalidating old session (user,email, session)=(%d,%s,%s)", this.getId(), this.getEmail(), session));
			session.invalidate();
		} else {
			logger.info("The user WAS NOT already logged in");
		}
		// In any case, we add the current user and HttpSession to the Map of logged users.
		loggedUsers.put(this, event.getSession());
		
	}

	@Override
	public void valueUnbound(HttpSessionBindingEvent event) {
		
		logger.info(String.format("Unbounding (user,email, session)=(%d,%s,%s)", this.getId(), this.getEmail(), event.getSession()));
		loggedUsers.remove(this);
		
	}
}
